package com.sychip.fhc

import android.app.Application
import androidx.lifecycle.DefaultLifecycleObserver
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.ProcessLifecycleOwner
import androidx.lifecycle.ViewModelStore
import androidx.lifecycle.ViewModelStoreOwner
import com.fhc.base.CrashHandler
import com.fhc.base.LocalManager
import com.fhc.base.TimberDebugTree
import com.fhc.base.TimberReleaseTree
import com.fhc.base.restartApp
import com.fhc.view.EnumAPPState
import com.sychip.fhc.app.pref.AppSetting
import com.sychip.fhc.app.pref.PrefDataStoreIf
import com.sychip.fhc.app.wsn.nav.WsnMainTabViewModel
import com.sychip.fhc.di.AppDataManager
import com.sychip.fhc.di.ApplicationScope
import dagger.hilt.android.HiltAndroidApp
import jakarta.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import timber.log.Timber
import java.io.PrintWriter
import java.io.StringWriter
import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty

/**
 * Main application
 *
 * @constructor Create empty Main application
 */
@HiltAndroidApp
class MainApplication : Application(), ViewModelStoreOwner {
    private val appViewModelStore = ViewModelStore()

    override val viewModelStore: ViewModelStore
        get() = appViewModelStore

    @Inject
    lateinit var appManager: AppDataManager

    @ApplicationScope
    @Inject
    lateinit var appScope: CoroutineScope

    // 注入PrefDataStoreIf用于读取配置
    @Inject
    lateinit var prefDataStore: PrefDataStoreIf

    var startTimeMillis: Long = System.currentTimeMillis()

    // 单例化的第三种方式：自定义一个非空且只能一次性赋值的委托属性
    companion object {
        private var instance: MainApplication by NotNullSingleValueVar()
        private lateinit var appState: EnumAPPState

        private var wsnTabViewModel: WsnMainTabViewModel? = null

        fun instance() = instance
    }

    override fun onCreate() {
        super.onCreate()
//        viewModelFactory = AppViewModelFactory(this)
        instance = this
        appState = EnumAPPState.NULL

        globalCrash()
//        Timber.plant(TimberReleaseTree("", MainApplication.instance, 3)) // Release模式下自定义日志行为

        configLog()

        startTimeMillis = System.currentTimeMillis()

        ProcessLifecycleOwner.get().lifecycle.addObserver(object : DefaultLifecycleObserver {
            override fun onStart(owner: LifecycleOwner) {
                Timber.i("onStart   >>>>>> ProcessLifecycleOwner  onStart")
                // 应用进入前台
            }

            override fun onStop(owner: LifecycleOwner) {
                Timber.i("onStop   >>>>>>  ProcessLifecycleOwner  onStop")
                // 应用进入后台
            }
        })

        appManager.saveThemeMode(appScope, true)
//        appManager.showToast(appScope, "MainApplication  设置已保存")
    }
    private var _appSetting: AppSetting? = null
    private fun setMockModeFalse(appSetting: AppSetting) {
        if (_appSetting != null) return
        _appSetting = appSetting
        appScope.launch {
            Timber.i("      Application     setMockModeFalse      ")
            prefDataStore.saveAppSettings(appSetting.copy(mockMode = false))
        }
    }
    private fun configLog() {
        appScope.launch {
            try {
                prefDataStore.getAppSettings().collect { appSetting ->
                    setMockModeFalse(appSetting)
                    Timber.uprootAll()
                    if (appSetting.logEnable) {
                        if (appSetting.mockMode) {
                            Timber.plant(TimberDebugTree()) // Debug模式下打印日志
                        } else {
                            if (IS_DEBUG) {
                                Timber.plant(TimberDebugTree()) // Debug模式下打印日志
                            }
                            Timber.plant(TimberReleaseTree("", instance, 3)) // Release模式下自定义日志行为
                        }
                    } else {
                        Timber.plant(Timber.DebugTree())
                    }
                    Timber.e("APP  logEnable: %s", appSetting.logEnable)
                }
            } catch (e: Exception) {
                if (IS_DEBUG) {
                    Timber.plant(TimberDebugTree()) // Debug模式下打印日志
                } else {
                    Timber.plant(Timber.DebugTree())
                }
                Timber.e("APP  logEnable: 读取应用配置时发生错误 %s", e.message)
            }

            Timber.e("》》》》》------ APP START ------《《《《《")
        }
    }

    private fun globalCrash() {
        if (!IS_DEBUG) {
            // 设置全局异常处理器
            val oldHandler = Thread.getDefaultUncaughtExceptionHandler()
            Thread.setDefaultUncaughtExceptionHandler(
                CrashHandler(applicationContext, oldHandler, onCrash = { exception ->
                    val stackTrace = StringWriter().apply {
                        exception.printStackTrace(PrintWriter(this))
                    }.toString()

                    Timber.e(stackTrace)
                    Timber.e(exception)

                    // 5. 可选：跳转错误页面 ,重启应用
                    restartApp(this, MainActivity::class.java, exception.message ?: "")
                })
            )
            LocalManager.initialize(this)
        }
    }

    /**
     * Set wsn main tab view model
     *
     * @param viewModel
     */
    fun setWsnMainTabViewModel(viewModel: WsnMainTabViewModel?) {
        wsnTabViewModel = viewModel
    }

//    /**
//     * Get wsn main tab view model
//     *
//     * @return
//     */
//    fun getWsnMainTabViewModel(): WsnMainTabViewModel? {
//        return wsnTabViewModel
//    }
    fun showBottomNavbar(show: Boolean) {
        wsnTabViewModel?.showBottomNavbar(show)
    }

    // 定义一个属性管理类，进行非空和重复赋值的判断
    private class NotNullSingleValueVar<T>() : ReadWriteProperty<Any?, T> {
        private var value: T? = null
        override fun getValue(thisRef: Any?, property: KProperty<*>): T {
            return value ?: throw IllegalStateException("application not initialized")
        }

        override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
            this.value = if (this.value == null) {
                value
            } else {
                throw IllegalStateException("application already initialized")
            }
        }
    }

    override fun onTerminate() {
        appScope.launch {
            try {
                prefDataStore.getAppSettings().collect { appSetting ->
                    setMockModeFalse(appSetting)
                }
            } catch (_: Exception) {
            }
        }
        appViewModelStore.clear()
        super.onTerminate()
    }
}
